<script setup lang="ts">
  import {
    ChildFormConfig,
    ComponentType,
    DataConnectConfig,
  } from '@/views/order/custom/hooks/types'
  import CustomInput from '../../../component-list/CustomInput.vue'
  import TextareaSetting from '../TextareaSetting.vue'
  import SingleSelectSetting from '../single-select-setting/index.vue'
  import MultipleSelectSetting from '../MultipleSelectSetting.vue'
  import DatetimeSetting from '../DatetimeSetting.vue'
  import UploadSetting from '../UploadSetting.vue'
  import DataConnectSetting from '../data-connect-setting/index.vue'
  import { ref } from 'vue'
  import InputSetting from '../InputSetting.vue'
  import { useGetComponentDefaultLabelByType } from '@/views/order/custom/hooks/useComponent'
  import { v4 as uuidv4 } from 'uuid'

  defineOptions({
    name: 'OrderCustomFormChildFormSetting',
  })

  const props = defineProps({
    componentId: {
      type: String,
      required: true,
    },
    templateId: {
      type: String,
      required: true,
    },
  })

  const emits = defineEmits<{
    (e: 'change'): void
  }>()

  // 绑定的值
  const value = defineModel<Array<ChildFormConfig>>('modelValue', { required: true })

  // 正在拖拽的字段的索引
  const dragingFieldIndex = ref(-1)

  // 正在编辑的字段索引
  const editingFieldIndex = ref(-1)

  /**
   * 更新字段的样式
   */
  const updateFieldDivSytle = () => {
    const fieldList = document.querySelectorAll('.field')
    if (fieldList) {
      fieldList.forEach((field) => {
        ;(field as HTMLDivElement).style.opacity = '1'
      })

      if (dragingFieldIndex.value >= 0 && dragingFieldIndex.value <= fieldList.length) {
        ;(fieldList[dragingFieldIndex.value] as HTMLDivElement).style.opacity = '0.2'
      }
    }
  }

  /**
   * 子表单添加字段点击事件
   */
  const handleChildFormAddField = (label: string, type: ComponentType) => {
    value.value.push({
      label: label || useGetComponentDefaultLabelByType(type),
      id: uuidv4(),
      fieldType: type,
      popoverVisible: false,
      inputConfig: {
        maxLength: 200,
        mode: 1,
        numberMax: 999999999,
        amountMax: 999999999.99,
        placeholder: '请输入',
      },
      textareaConfig: {
        maxLength: 200,
        placeholder: '请输入',
      },
      singleSelectConfig: {
        options: [
          { label: '选项1', value: uuidv4() },
          { label: '选项2', value: uuidv4() },
          { label: '选项3', value: uuidv4() },
        ],
        placeholder: '请选择',
        beControlVisibleRules: [],
      },
      multipleSelectConfig: {
        options: [
          { label: '选项1', value: 1 },
          { label: '选项2', value: 2 },
          { label: '选项3', value: 3 },
        ],
        placeholder: '请选择',
      },
      dateTimeConfig: {
        dateTimeType: 'date',
        placeholder: '请选择日期',
      },
      fileUploadConfig: {
        type: 'picture',
        num: 10,
        size: 50,
      },
      dataConnectConfig: {
        type: '',
        fieldList: [],
        showFormFieldList: [],
        fillRules: [],
        selectMode: 1,
      },
      beAssociated: false,
      beControlVisible: false,
    })
    emits('change')
  }

  /**
   * 字段删除事件
   * @param {number} fieldIndex - 字段索引
   */
  const handleFieldDel = (fieldIndex: number) => {
    value.value[fieldIndex].popoverVisible = !value.value[fieldIndex].popoverVisible
    value.value.splice(fieldIndex, 1)
    emits('change')
  }

  /**
   * 字段开始拖拽事件
   * @param {Event} e - 事件对象
   */
  const handleFieldDragStart = (e: Event, index: number) => {
    dragingFieldIndex.value = index
    updateFieldDivSytle()
  }

  /**
   * 字段结束拖拽事件
   */
  const handleFieldDragEnd = () => {
    dragingFieldIndex.value = -1
    updateFieldDivSytle()
    emits('change')
  }

  /**
   * 字段被拖拽进另一个字段内时触发，进入一次触发一次，目的是更新字段的顺序
   * @param {number} fieldIndex - 字段索引
   */
  const handleDragenter = (fieldIndex: number) => {
    if (dragingFieldIndex.value !== fieldIndex) {
      const sourceField = value.value[dragingFieldIndex.value]
      value.value.splice(dragingFieldIndex.value, 1)
      value.value.splice(fieldIndex, 0, sourceField)
      dragingFieldIndex.value = fieldIndex
    }
    updateFieldDivSytle()
  }

  /**
   * 字段被拖拽进另一个字段内时触发，会频繁触发，目的是允许一个字段被拖进另一个字段内
   * @param {Event} e - 事件对象
   */
  const handleFieldDragover = (e: Event) => {
    e.preventDefault()
  }

  /**
   * 字段编辑完成按钮点击事件
   */
  const onFieldEditFinishClick = () => {
    editingFieldIndex.value = -1
    emits('change')
  }

  /**
   * 关联数据的字段填充规则更新事件
   * @param {DataConnectConfig['fillRules']} rules - 字段填充规则
   */
  const handleDataConnectSettingFieldFillRuleChange = (rules: DataConnectConfig['fillRules']) => {
    if (value.value[editingFieldIndex.value]) {
      value.value[editingFieldIndex.value].dataConnectConfig.fillRules = rules.map((rule) => {
        if (rule.fillMode === 1) {
          handleChildFormAddField(rule.fromFieldName, 'input')
          rule.fillMode = 2
          rule.toFieldName = value.value.at(-1).label
          rule.toFieldId = value.value.at(-1).id
        }
        return rule
      })
    }
  }
</script>

<template>
  <div class="order-custom-form-child-form-setting">
    <template v-if="editingFieldIndex === -1">
      <div class="label">
        <div class="text">子字段</div>
        <el-dropdown
          trigger="click"
          @command="(type: ComponentType) => handleChildFormAddField('', type)"
        >
          <h-link>+添加子字段</h-link>

          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item command="input">单行输入</el-dropdown-item>
              <el-dropdown-item command="textarea">多行输入</el-dropdown-item>
              <el-dropdown-item command="single-select">下拉单选</el-dropdown-item>
              <el-dropdown-item command="multiple-select">下拉多选</el-dropdown-item>
              <el-dropdown-item command="date-time">日期时间</el-dropdown-item>
              <el-dropdown-item command="file-upload">文件上传</el-dropdown-item>
              <el-dropdown-item command="data-connect">关联数据</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
      <div ref="fieldListDiv" class="field-list">
        <div
          v-for="(field, fieldIndex) in value"
          :key="fieldIndex"
          class="field"
          draggable="true"
          @dragstart="handleFieldDragStart($event, fieldIndex)"
          @dragend="handleFieldDragEnd"
          @dragenter="handleDragenter(fieldIndex)"
          @dragover="handleFieldDragover"
        >
          <div class="field-name">
            <custom-input
              v-model="field.label"
              placeholder="请输入字段名称"
              @input="emits('change')"
            />
          </div>
          <div class="sort">
            <i class="iconfont icon-paixu"></i>
          </div>
          <el-popover :visible="field.popoverVisible" :width="200" placement="bottom-end">
            <template #reference>
              <div class="del" @click="field.popoverVisible = true">
                <i class="iconfont icon-del"></i>
              </div>
            </template>
            <template #default>
              <div class="field-del-panel">
                <div class="title">提示</div>
                <div class="content">确定要删除该字段吗？</div>
                <div class="footer">
                  <h-plain-button
                    type="error"
                    :height="18"
                    :width="36"
                    @click="handleFieldDel(fieldIndex)"
                    >确定</h-plain-button
                  >
                  <h-button :height="18" :width="36" @click="field.popoverVisible = false"
                    >取消</h-button
                  >
                </div>
              </div>
            </template>
          </el-popover>
          <div class="edit" @click="editingFieldIndex = fieldIndex">
            <i class="iconfont icon-gongju-05"></i>
          </div>
        </div>
      </div>
    </template>
    <div v-if="editingFieldIndex !== -1" class="field-edit-form">
      <h-button type="primary" :width="400" @click="onFieldEditFinishClick">完成</h-button>

      <!-- 单行文本 -->
      <input-setting
        v-if="value[editingFieldIndex].fieldType === 'input'"
        v-model="value[editingFieldIndex].inputConfig"
      />

      <!-- 多行文本 -->
      <textarea-setting
        v-if="value[editingFieldIndex].fieldType === 'textarea'"
        v-model="value[editingFieldIndex].textareaConfig"
      />

      <!-- 下拉单选 -->
      <single-select-setting
        v-if="value[editingFieldIndex].fieldType === 'single-select'"
        v-model="value[editingFieldIndex].singleSelectConfig"
        :template-id="props.templateId"
      />

      <!-- 下拉多选 -->
      <multiple-select-setting
        v-if="value[editingFieldIndex].fieldType === 'multiple-select'"
        v-model="value[editingFieldIndex].multipleSelectConfig"
      />

      <!-- 日期时间 -->
      <datetime-setting
        v-if="value[editingFieldIndex].fieldType === 'date-time'"
        v-model="value[editingFieldIndex].dateTimeConfig"
      />

      <!-- 文件上传 -->
      <upload-setting
        v-if="value[editingFieldIndex].fieldType === 'file-upload'"
        v-model="value[editingFieldIndex].fileUploadConfig"
      />

      <!-- 关联数据 -->
      <data-connect-setting
        v-if="value[editingFieldIndex].fieldType === 'data-connect'"
        v-model="value[editingFieldIndex].dataConnectConfig"
        :parent-component-type="'child-form'"
        :child-form-id="props.componentId"
        @field-fill-rule-change="handleDataConnectSettingFieldFillRuleChange"
      />
    </div>
  </div>
</template>

<style scoped lang="scss">
  .field-del-panel {
    display: flex;
    flex-direction: column;

    .title {
      font-weight: bold;
      color: #000;
    }

    .content {
      white-space: nowrap;
    }

    .footer {
      display: flex;
      justify-content: flex-end;
      margin-top: 8px;
      column-gap: 4px;
    }
  }

  .order-custom-form-child-form-setting {
    display: flex;
    flex-direction: column;
    row-gap: 14px;

    .label {
      display: flex;
      align-items: center;
      column-gap: 12px;
    }

    .field-list {
      display: flex;
      flex-direction: column;
      row-gap: 8px;
      position: relative;

      .field {
        display: flex;
        column-gap: 8px;
        align-items: center;
        width: 100%;

        .field-name {
          flex: 1;
        }

        .icon-paixu {
          cursor: move;

          &:hover {
            color: #007cff;
          }
        }

        .icon-del {
          cursor: pointer;

          &:hover {
            color: #f56c6c;
          }
        }

        .icon-gongju-05 {
          cursor: pointer;

          &:hover {
            color: #007cff;
          }
        }
      }

      .field.moving {
        opacity: 0.2;
      }
    }

    .field-edit-form {
      display: flex;
      flex-direction: column;
      row-gap: 12px;
    }
  }
</style>
